#include "comm.hpp"
#include "log.hpp"

string KeyToHex(key_t k)
{
    char buffer[32];
    snprintf(buffer,sizeof buffer ,"0x%x",k);
    return buffer;
}


int main()
{
    // 1.创建公共的key值
    key_t key = ftok(PATH_NAME,PROJ_ID);
    assert(key != -1);
    log("创建key值成功",DEBUG) << "server key =" <<  KeyToHex(key) << endl;

    // 2. 创建共享内存 -- 建议要创建一个全新的共享内存 -- 通信的发起者
    int shmid = shmget(key,SHM_SIZE,IPC_CREAT | IPC_EXCL | 0666);
    if(shmid == -1)
    {
        perror("shmget");
        exit(1);
    }
    log("创建共享内存成功",DEBUG) << "shmid =" << shmid << endl;
    sleep(8);
    // 3. 将指定的共享内存，挂接到自己的地址空间

    char* shmaddr = (char*)shmat(shmid,nullptr,0);
    if(shmaddr == nullptr)
    {
        perror("shmaddr");
        exit(2);
    }
    log("共享内存与地址空间映射建立成功",DEBUG) << "shmid =" << shmid << endl;    
    sleep(8);

    // 这里就是通信的逻辑了

    // 4. 将指定的共享内存，从自己的地址空间中去关联
    int ret = shmdt(shmaddr);
    if(ret == -1)
    {
        perror("shmdt");
        exit(3);
    }
    log("共享内存与地址空间去关联成功",DEBUG) << "shmid =" << shmid << endl;  
    sleep(8);

    // 5. 删除共享内存,IPC_RMID即便是有进程和当下的shm挂接，依旧删除共享内存
    ret = shmctl(shmid,IPC_RMID,nullptr);
    if(ret == -1)
    {
        perror("shmctl");
        exit(3);
    }
    log("共享内存删除成功",DEBUG) << "shmid =" << shmid << endl;  


    // client 要不要chmctl删除呢？不需要！！
    return 0;
}